﻿using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.Linq.Extensions;
using System.Linq.Dynamic.Core;
using Abp.Runtime.Session;
using Microsoft.EntityFrameworkCore;
using Abp.Timing;
using Magicodes.WeChat.Application;
using Magicodes.WeChat.Application.User.WeChatUser;
using Magicodes.WeChat.Application.User.WeChatUser.Dto;
using Magicodes.WeChat.Authorization;
using Magicodes.WeChat.User.Dto;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Dynamic;
using System.Threading.Tasks;
using Abp.Dependency;
using Abp.Events.Bus;
using Magicodes.WeChat.Application.Events;
using Abp.Domain.Entities;
using Abp.Extensions;
using Abp.UI;

namespace Magicodes.WeChat.User
{
    /// <summary>
    /// 粉丝信息
    /// </summary>
    public class WeChatUserAppService : AppServiceBase, IWeChatUserAppService
    {
        private readonly IRepository<WeChatUser, string> _weChatUserRepository;
        private readonly IWeChatUserCache _weChatUserCache;
        private readonly IEventBus _eventBus;

        public WeChatUserAppService(
            IRepository<WeChatUser, string> weChatUserRepository,
            IWeChatUserCache weChatUserCache, IEventBus eventBus) : base()
        {
            _weChatUserRepository = weChatUserRepository;
            _weChatUserCache = weChatUserCache;
            _eventBus = eventBus;
        }

        /// <summary>
        /// 获取粉丝信息列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [AbpAuthorize(WeChatPermissions.Roots_Tenants_WeChatUser)]
        public async Task<PagedResultDto<WeChatUserListDto>> GetWeChatUsers(GetWeChatUsersInput input)
        {
            var query = CreateWeChatUsersQuery(input);

            var resultCount = await query.CountAsync();
            var results = await query
                .AsNoTracking()
                .OrderBy(input.Sorting)
                .PageBy(input)
                .ToListAsync();

            return new PagedResultDto<WeChatUserListDto>(resultCount, results.MapTo<List<WeChatUserListDto>>());
        }

        private IQueryable<WeChatUser> CreateWeChatUsersQuery(GetWeChatUsersInput input)
        {
            var query = _weChatUserRepository.GetAll();

            return query;
        }

        /// <summary>
        /// 根据OpenId获取粉丝信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<WeChatUserListDto> GetWeChatUserById(string id)
        {
            if (id.IsNullOrWhiteSpace())
            {
                throw new UserFriendlyException("id不能为空!");
            }
            WeChatUserListDto WeChatUserListDto = null;
            using (UnitOfWorkManager.Current.DisableFilter(AbpDataFilters.MayHaveTenant, AbpDataFilters.MustHaveTenant))
            {
                //从缓存实体中获取
                WeChatUserListDto = await _weChatUserCache.GetAsync(id);
                //if (WeChatUserListDto == null)
                //{
                //    var model = await _weChatUserRepository.GetAsync(id);
                //    WeChatUserListDto = model.MapTo<WeChatUserListDto>();
                //}
            }
            return WeChatUserListDto;
        }

        /// <summary>
        /// 绑定用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<WeChatUserListDto> BindUser(BindUserIdDto input)
        {
            using (UnitOfWorkManager.Current.DisableFilter(AbpDataFilters.MayHaveTenant, AbpDataFilters.MustHaveTenant))
            {
                var info = await _weChatUserRepository.GetAsync(input.Id);
                info.UserId = input.UserId;

                var user = info.MapTo<WeChatUserListDto>();
                user.EventKey = info.GetData<string>("EventKey");
                return user;
            }
        }

        /// <summary>
        /// 移除用户绑定
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task RemoveBind(string id)
        {
            using (UnitOfWorkManager.Current.DisableFilter(AbpDataFilters.MayHaveTenant, AbpDataFilters.MustHaveTenant))
            {
                var info = await _weChatUserRepository.GetAsync(id);
                info.UserId = null;
            }
        }

        ///// <summary>
        ///// 创建并缓存粉丝
        ///// </summary>
        ///// <param name="input"></param>
        ///// <returns></returns>
        //public async Task CreateAndCacheWeChatUser(CreateOrUpdateWeChatUserDto input)
        //{
        //    var weChatUser = new WeChatUser()
        //    {
        //        Subscribe = input.WeChatUser.Subscribe,
        //        NickName = input.WeChatUser.NickName,
        //        City = input.WeChatUser.City,
        //        Country = input.WeChatUser.Country,
        //        Province = input.WeChatUser.Province,
        //        Language = input.WeChatUser.Language,
        //        HeadImgUrl = input.WeChatUser.HeadImgUrl,
        //        SubscribeTime = input.WeChatUser.SubscribeTime,
        //        UnionId = input.WeChatUser.UnionId,
        //        Remark = input.WeChatUser.Remark,
        //        Sex = input.WeChatUser.Sex,
        //        GroupId = input.WeChatUser.GroupId,
        //        CreatorUserId = AbpSession.GetUserId(),
        //        CreationTime = Clock.Now,
        //        TenantId = input.WeChatUser.TenantId ?? AbpSession.TenantId
        //    };
        //    UnitOfWorkManager.Current.Completed += (sender, args) =>
        //    {
        //        var user = sender as WeChatUser;
        //        var editUser = user.MapTo<WeChatUserEditDto>();
        //        if (editUser != null)
        //        {
        //            _cacheManager.SetWeChatUserCache(editUser.Id, editUser);
        //            Logger.Debug("weChatUser已缓存");
        //        }
        //        else
        //        {
        //            Logger.Warn("weChatUser");
        //        }
        //    };
        //    await _weChatUserRepository.InsertAsync(weChatUser);

        //}

        //[AbpAuthorize(WeChatPermissions.Roots_Tenants_WeChatUser_Create, WeChatPermissions.Roots_Tenants_WeChatUser_Edit)]
        public async Task<GetWeChatUserForEditOutput> GetWeChatUserForEdit(string id)
        {
            WeChatUserEditDto editDto;
            if (!string.IsNullOrEmpty(id))
            {
                var info = await _weChatUserRepository.GetAsync(id);
                editDto = info.MapTo<WeChatUserEditDto>();
            }
            else
            {
                editDto = new WeChatUserEditDto();

            }
            return new GetWeChatUserForEditOutput
            {
                WeChatUser = editDto
            };
        }




        //[AbpAuthorize(WeChatPermissions.Roots_Tenants_WeChatUser_Create, WeChatPermissions.Roots_Tenants_WeChatUser_Edit)]
        public async Task CreateOrUpdateWeChatUser(CreateOrUpdateWeChatUserDto input)
        {
            if (!string.IsNullOrEmpty(input.WeChatUser.Id))
            {
                if (_weChatUserRepository.GetAll().Any(p => p.Id == input.WeChatUser.Id))
                {
                    Logger.Warn("WeChatUser[" + input.WeChatUser.Id + "]已存在！");
                    return;
                }
                await CreateWeChatUserAsync(input);
            }
            else
            {
                await UpdateWeChatUserAsync(input);
            }
        }

        [AbpAuthorize(WeChatPermissions.Roots_Tenants_WeChatUser_Delete)]
        public async Task DeleteWeChatUser(EntityDto<string> input)
        {
            var weChatUser = await _weChatUserRepository.GetAsync(input.Id);
            weChatUser.IsDeleted = true;
            weChatUser.DeleterUserId = AbpSession.GetUserId();
            weChatUser.DeletionTime = Clock.Now;

        }

        //[AbpAuthorize(WeChatPermissions.Roots_Tenants_WeChatUser_Create)]
        protected virtual async Task CreateWeChatUserAsync(CreateOrUpdateWeChatUserDto input)
        {
            var weChatUser = new WeChatUser()
            {
                Id = input.WeChatUser.Id,
                Subscribe = input.WeChatUser.Subscribe,
                NickName = input.WeChatUser.NickName,
                City = input.WeChatUser.City,
                Country = input.WeChatUser.Country,
                Province = input.WeChatUser.Province,
                Language = input.WeChatUser.Language,
                HeadImgUrl = input.WeChatUser.HeadImgUrl,
                SubscribeTime = input.WeChatUser.SubscribeTime,
                UnionId = input.WeChatUser.UnionId,
                Remark = input.WeChatUser.Remark,
                Sex = input.WeChatUser.Sex,
                GroupId = input.WeChatUser.GroupId,
                CreatorUserId = AbpSession.UserId,
                CreationTime = Clock.Now,
                TenantId = AbpSession.TenantId ?? input.WeChatUser.TenantId,
                AppId = input.WeChatUser.AppId
                //LastModifierUserId = null

            };
            if (!input.WeChatUser.EventKey.IsNullOrEmpty())
                weChatUser.SetData("EventKey", input.WeChatUser.EventKey);
            await _weChatUserRepository.InsertAsync(weChatUser);

            CurrentUnitOfWork.Completed += async (o, args) =>
            {
                await _eventBus.TriggerAsync(new WeChatUserDataCreatedEventData()
                {
                    WeChatUser = weChatUser
                });
            };

            await CurrentUnitOfWork.SaveChangesAsync();
        }

        //[AbpAuthorize(WeChatPermissions.Roots_Tenants_WeChatUser_Edit)]
        protected virtual async Task UpdateWeChatUserAsync(CreateOrUpdateWeChatUserDto input)
        {
            Debug.Assert(input.WeChatUser.Id != null, "必须设置input.WeChatUser.Id的值");

            var weChatUser = await _weChatUserRepository.GetAsync(input.WeChatUser.Id);
            weChatUser.Subscribe = input.WeChatUser.Subscribe;
            weChatUser.NickName = input.WeChatUser.NickName;
            weChatUser.City = input.WeChatUser.City;
            weChatUser.Country = input.WeChatUser.Country;
            weChatUser.Province = input.WeChatUser.Province;
            weChatUser.Language = input.WeChatUser.Language;
            weChatUser.HeadImgUrl = input.WeChatUser.HeadImgUrl;
            weChatUser.SubscribeTime = input.WeChatUser.SubscribeTime;
            weChatUser.UnionId = input.WeChatUser.UnionId;
            weChatUser.Remark = input.WeChatUser.Remark;
            weChatUser.Sex = input.WeChatUser.Sex;
            weChatUser.GroupId = input.WeChatUser.GroupId;
            if (!input.WeChatUser.EventKey.IsNullOrEmpty())
                weChatUser.SetData("EventKey", input.WeChatUser.EventKey);
        }

        /// <summary>
        /// 根据用户Id获取OpenId列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [UnitOfWork(false)]
        public async Task<string[]> GetOpenIdsByUserIds(GetOpenIdsByUserIdsInput input)
        {
            using (CurrentUnitOfWork.DisableFilter(AbpDataFilters.MayHaveTenant))
            {
                var openIds = await _weChatUserRepository.GetAll().Where(p => p.TenantId == input.Key && input.UserIds.Contains(p.UserId)).Select(p => p.Id).ToArrayAsync();
                return openIds;
            }
        }

        [UnitOfWork(false)]
        public async Task<WeChatUserListDto> GetWeChatUserByUserId(string userId)
        {
            using (CurrentUnitOfWork.DisableFilter(AbpDataFilters.MayHaveTenant))
            {
                var user = await _weChatUserRepository.GetAll().FirstOrDefaultAsync(p => p.UserId == userId);
                return user.MapTo<WeChatUserListDto>();
            }
        }
    }
}